package com.xxxtea.dto;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 分页查询数据传输对象
 *
 * 用于封装分页查询的通用参数，包括：
 * - 查询条件参数
 * - 分页信息（页码、页大小）
 * - 排序规则
 * - 参数处理和转换
 *
 * 支持泛型查询参数
 * 使用Swagger注解进行API文档生成
 * 使用Lombok注解简化代码
 *
 * @author badman
 * @since 1.0.0
 */
@Data
public class PageQuery<T> {
	/**
	 * 查询参数
	 * 泛型参数，支持任意类型的查询条件
	 */
	@ApiModelProperty("查询参数")
	private T param;

	/**
	 * 页号
	 * 当前页码，默认为1
	 */
	@ApiModelProperty("页号")
	private Integer page = 1;

	/**
	 * 页大小
	 * 每页记录数，默认为10
	 */
	@ApiModelProperty("页数")
	private Integer size = 10;

	/**
	 * 排序规则列表
	 * 用于指定查询结果的排序方式
	 */
	private List<OrderItem> orders = new ArrayList<>();

	/**
	 * 转换为MyBatis-Plus的Page对象
	 * 
	 * @param <A> 返回Page对象的泛型类型
	 * @return MyBatis-Plus的Page对象
	 */
	public <A> Page<A> toPage() {
		Page<A> pageRequest = new Page<>(page, size);
		// 将驼峰命名转换为下划线命名
		for (OrderItem order : orders) {
			order.setColumn(StrUtil.toUnderlineCase(order.getColumn()));
		}
		pageRequest.setOrders(orders);
		return pageRequest;
	}

	/**
	 * 获取处理后的查询参数
	 * 将空字符串转换为null，避免查询条件错误
	 * 
	 * @return 处理后的查询参数
	 */
	public T getParam() {
		if (param == null) {
			return null;
		}
		// 遍历参数对象的所有字段，将空字符串转换为null
		for (Field field : ReflectUtil.getFields(param.getClass())) {
			if (field.getType() == String.class && "".equals(ReflectUtil.getFieldValue(param, field))) {
				ReflectUtil.setFieldValue(param, field, null);
			}
		}
		return param;
	}
}